use std::collections::{HashMap, HashSet};
use std::str::FromStr;
use crate::db::dao::im_message_dao::{change_message_action_status, change_message_action_status2, query_message_by_server_ids};
use crate::db::db::Db;
use crate::db::db_transaction::transaction;
use crate::db::pojo::pojo::{ImMessageActionData, ImMessageActionStatus};
use crate::business::websocket::dto::im_message_dto::{MessageActionItem};
use crate::db::dao::im_message_send_dao::{change_message_send_action_status, message_send_is_syn_end};

pub struct ImMessageActionService;

impl ImMessageActionService {

    pub fn save_message_actions(&self, user_id: String, action_item_list: &Vec<MessageActionItem>) {
        let db = Db::open();
        transaction(db.clone(), move |db: Db| {
            self.save_message_actions_business(db, user_id.clone(), action_item_list)
        });
    }

    fn save_message_actions_business(&self, db: Db, user_id: String, action_item_list: &Vec<MessageActionItem>) {
        let message_action_map = action_item_list.iter().fold(HashMap::new(), |mut acc, action_item| {
            acc.entry(&action_item.message_id).or_insert(vec![]).push(action_item);
            acc
        });
        let server_ids = message_action_map.keys().map(|k| k.as_ref()).collect::<Vec<&str>>();
        log::info!("db message action message ids: {:?}", server_ids);
        let db_messages = query_message_by_server_ids(db.clone(), &user_id, server_ids);

        let mut group_messages = Vec::new();
        let mut p2p_message_action_list = Vec::new();
        let mut group_message_action_list= Vec::new();

        for message in db_messages.iter() {
            let message_action_list = message_action_map.get(&message.server_id.clone().unwrap()).unwrap();
            for message_action_item in message_action_list {
                let action_status = ImMessageActionStatus::from_str(&message_action_item.message_action_status).unwrap();
                if message.is_p2p() {
                    p2p_message_action_list.push(ImMessageActionData {
                        message_id: message.id.unwrap(),
                        user_id: message_action_item.user_id.clone(),
                        action_status,
                    });
                } else {
                    group_messages.push(message);
                    group_message_action_list.push(ImMessageActionData {
                        message_id: message.id.unwrap(),
                        user_id: message_action_item.user_id.clone(),
                        action_status,
                    });
                }
            }
        }

        if p2p_message_action_list.len() > 0 {
            change_message_action_status(db.clone(), p2p_message_action_list);
        }

        if group_message_action_list.len() > 0 {
            change_message_send_action_status(db.clone(), group_message_action_list);
        }

        let mut read_complete_message_id_set = HashSet::new();
        let mut withdraw_complete_message_id_set = HashSet::new();
        for group_message in group_messages {
            let is_syn_end = message_send_is_syn_end(db.clone(), group_message.id.unwrap());
            if is_syn_end {
                match group_message.action_status {
                    ImMessageActionStatus::Withdraw | ImMessageActionStatus::Withdrawed => {
                        withdraw_complete_message_id_set.insert(group_message.id.unwrap());
                    }
                    ImMessageActionStatus::Read | ImMessageActionStatus::Readed => {
                        read_complete_message_id_set.insert(group_message.id.unwrap());
                    }
                    _ => {
                        log::warn!("不支持这种状态: {:?}", group_message.action_status);
                    }
                }
            }
        }

        if !read_complete_message_id_set.is_empty() {
            change_message_action_status2(db.clone(), read_complete_message_id_set, ImMessageActionStatus::Readed);
        }

        if withdraw_complete_message_id_set.len() > 0 {
            change_message_action_status2(db.clone(), withdraw_complete_message_id_set, ImMessageActionStatus::Withdrawed);
        }
    }
}